package com.rsstuan.crawl.impl;

import java.util.ArrayList;
import java.util.List;

import org.mortbay.log.Log;

import com.rsstuan.crawl.ICrawler;
import com.rsstuan.crawl.data.CrawledData;
import com.rsstuan.data.ArticleData;
import com.rsstuan.data.Channel;
import com.rsstuan.data.FeedOut;
import com.rsstuan.parser.FeedParser;
import com.rsstuan.storage.IArticleStorage;
import com.rsstuan.storage.IChannelStorage;
import com.rsstuan.storage.data.ArticleStorageData;
import com.rsstuan.storage.impl.GoogleArticleStorage;
import com.rsstuan.storage.impl.GoogleChannelStorage;
import com.rsstuan.utils.IdUtils;

public class SimpleCrawler implements ICrawler {

	private IChannelStorage channelStorage;
	private IArticleStorage articleStorage;
	
	public SimpleCrawler() {
		channelStorage = new GoogleChannelStorage();
		articleStorage = new GoogleArticleStorage();
	}
	@Override
	public void doSave(CrawledData data) {
		try {
			FeedParser parser = new FeedParser();
			FeedOut feedOut = parser.parse(data.getData());
			if (feedOut != null) {
				long channelId;
				if (data.getFeedId() != null)
					channelId = data.getFeedId();
				else
					channelId = IdUtils.generateFeedId(data.getFeedUrl());
				Channel channel = channelStorage.getChannel(channelId);
				if (channel == null) {
					return;
				}
				
				
				int wanted = 100;
				ArticleStorageData[] existArticles = articleStorage.getArticles(channelId, wanted);
				List<ArticleData> toAdd = new ArrayList<ArticleData>();
				for (ArticleData article : feedOut.getArticles()) {
					if (existArticles != null && !checkExist(article, existArticles)) {
						toAdd.add(article);
					}
				}
				
				int newArticle = 0;
				if (toAdd.size() > 0) {
					newArticle = articleStorage.saveArticles(channel, toAdd.toArray(new ArticleData[0]));
				}
				
				if (newArticle > 0) {
					channelStorage.updateArticleCount(channel, newArticle);
				}
				Log.info("SAVE " + newArticle + " articles");
				
			}
		}
		catch (Exception e) {
			Log.warn("save articles failed", e);
		}
		
	}
	
	private boolean checkExist(ArticleData article,
			ArticleStorageData[] existArticles) {
		for (ArticleStorageData existArticle : existArticles) {
			if (article.getDigest().equals(existArticle.getDigest()))
				return true;
			else if (article.getAuthor() == existArticle.getAuthor()
					&& article.getLink() == existArticle.getLink())
				return true;
		}

		return false;

	}

}
